﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Input;

using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace MapLibrary
{
    /// <summary>
    /// This represents a single layer of the map, with possibilities of editing.
    /// </summary>
    class EditorLayer
    {

        protected const int DEACTIVATE_ALPHA = 0;
        protected const int ACTIVATE_ALPHA = 255;

        /// <summary>
        /// Contains all of the editor nodes of this layer.
        /// </summary>
        protected List<EditorNode> mEditorNodes;

        /// <summary>
        /// Layer that this EditorLayer wraps.
        /// </summary>
        protected Layer mEditingLayer;

        public EditorLayer(Layer pLayer)
        {
            mEditingLayer = pLayer;
            mEditorNodes = new List<EditorNode>();
        }

        public virtual void Draw(SpriteBatch pBatch, WorldViewport pViewport)
        {
            foreach (EditorNode Node in mEditorNodes)
            {
                Node.Draw(pBatch, pViewport);
            }
        }
        
        public void Load(ContentManager pContent, GraphicsDevice pDevice)
        {
            foreach(MapNode node in mEditingLayer.MapNodes)
            {
                EditorNode tNode = new EditorNode(node);
                tNode.Load(pDevice, pContent);
                mEditorNodes.Add(tNode);
            }
        }

        /// <summary>
        /// Set the layer to currently NOT being edited.  Makes the nodes less visible so
        /// that the user can see the nodes in the lower layers.
        /// </summary>
        public void DeactivateLayer()
        {
            foreach (EditorNode tNode in mEditorNodes)
            {
                tNode.Alpha = ACTIVATE_ALPHA;
                tNode.Hover = false;
                tNode.DrawBoundingBox = false;
            }
        }

        /// <summary>
        /// Set layer to currently being edited.  Changes visibility of the nodes
        /// </summary>
        public void ActivateLayer()
        {
            foreach (EditorNode tNode in mEditorNodes)
            {
                tNode.Alpha = ACTIVATE_ALPHA;
                tNode.DrawBoundingBox = true;
            }
        }

        /// <summary>
        /// Updates the hover action on this layer
        /// </summary>
        /// <param name="Input">game input to get mouse info</param>
        /// <param name="pViewport">viewport for the world</param>
        public void UpdateNodeHover(GameInput Input, WorldViewport pViewport)
        {
            bool hasHovered = false;
            foreach (EditorNode Node in mEditorNodes)
            {
                Rectangle rect = Node.BuildNodeRectangle(pViewport);

                /**
                 * Josh's Note: since the map nodes are being drawn at their center, the rectangle
                 * returned by this method will not be exactly at the correct screen location.  Thus
                 * we need to translate it.
                 */
                int centerXDist = rect.Center.X - rect.X;
                int centerYDist = rect.Center.Y - rect.Y;

                //translate rect up and left
                rect.X = rect.X - centerXDist;
                rect.Y = rect.Y - centerYDist;

                if (Input.IsMouseInRectangle(rect, Node.Rotation) && !hasHovered)
                {
                    Node.Hover = true;
                    hasHovered = true;
                }
                else
                    Node.Hover = false;
            }
        }

        public virtual void AddNode(EditorNode pNode)
        {
            mEditorNodes.Add(pNode);
        }

        /// <summary>
        /// Returns the node in this layer that is being hovered over.
        /// </summary>
        /// <param name="Input">input to receive mouse information</param>
        /// <param name="pViewport">world viewport</param>
        /// <returns></returns>
        public EditorNode GetHoveredNode(GameInput Input, WorldViewport pViewport)
        {
            bool hasHovered = false;
            foreach (EditorNode Node in mEditorNodes)
            {
                Rectangle rect = Node.BuildNodeRectangle(pViewport);

                /**
                 * Josh's Note: since the map nodes are being drawn at their center, the rectangle
                 * returned by this method will not be exactly at the correct screen location.  Thus
                 * we need to translate it.
                 */
                int centerXDist = rect.Center.X - rect.X;
                int centerYDist = rect.Center.Y - rect.Y;

                //translate rect up and left
                rect.X = rect.X - centerXDist;
                rect.Y = rect.Y - centerYDist;

                if (Input.IsMouseInRectangle(rect, Node.Rotation) && !hasHovered)
                {
                    Node.Hover = true;
                    hasHovered = true;
                    return Node;
                }
                else
                    Node.Hover = false;
            }
            return null;
        }

    }
}
